home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 22 / CU Amiga Magazine's Super CD-ROM 22 (1998)(EMAP Images)(GB)[!][issue 1998-05].iso / PowerPC / Programming / vbcc / main.c < prev    next >
C/C++ Source or Header  |  1998-02-18  |  21KB  |  571 lines

  1. /*  $VER: vbcc (main.c) V0.4    */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int endok=1;
  8. int line,errors;
  9.  
  10. char *multname[]={"","s"};
  11. void raus(void)
  12. /*  Beendet das Programm                                            */
  13. {
  14.     if(DEBUG) printf("raus()\n");
  15.     if(!endok) printf("unexpected end of file\n");
  16.     if(errors) printf("%d error%s found!\n",errors,multname[errors>1]);
  17.     while(nesting>=0) leave_block();
  18.     if(in[0]&&(c_flags[17]&USEDFLAG)) fclose(in[0]);
  19.     cleanup_cg(out);
  20.     if(ppout) fclose(ppout);
  21.     if(out) fclose(out);
  22.     if(ic1) fclose(ic1);
  23.     if(ic2) fclose(ic2);
  24.     if(!(c_flags[17]&USEDFLAG)) pp_free();
  25.     if(endok&&!errors) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE);
  26. }
  27.  
  28. int eof;
  29.  
  30. void translation_unit(void)
  31. /*  bearbeitet translation_unit                                     */
  32. /*  hier z.Z. nur provisorisch                                      */
  33. {
  34.     while(1){
  35.         killsp();
  36.         if(c_flags[18]&USEDFLAG){
  37.             fputs(string,ppout);fputc('\n',ppout);
  38.             s=string;*s=0;
  39.         }else{
  40.             if(eof||(!isalpha((unsigned char)*s)&&*s!='_')){
  41.                 if(!eof) error(0);
  42.                 raus();
  43.             }
  44.             endok=0;
  45.             var_declaration();
  46.             endok=1;
  47.         }
  48.     }
  49. }
  50.  
  51. void dontwarn(char *p)
  52. /*  schaltet flags fuer Meldung auf DONTWARN    */
  53. {
  54.     int i;
  55.     if(*p!='=') error(4,"-dontwarn");
  56.     i=atoi(p+1);
  57.     if(i>=err_num) error(159,i);
  58.     if(i<0){
  59.         for(i=0;i<err_num;i++)
  60.             if(!(err_out[i].flags&(ANSIV|FATAL)))
  61.                 err_out[i].flags|=DONTWARN;
  62.         return;
  63.     }
  64.     if(err_out[i].flags&(ANSIV|FATAL)) error(160,i);
  65.     err_out[i].flags|=DONTWARN;
  66. }
  67. void warn(char *p)
  68. /*  schaltet Warnung fuer Meldung ein           */
  69. /*  wenn Nummer<0 sind alle Warnungen ein       */
  70. {
  71.     int i;
  72.     if(*p!='=') error(4,"-warn");
  73.     i=atoi(p+1);
  74.     if(i>=err_num) error(159,i);
  75.     if(i<0){
  76.         for(i=0;i<err_num;i++) err_out[i].flags&=~DONTWARN;
  77.         return;
  78.     }else err_out[i].flags&=~DONTWARN;
  79. }
  80.  
  81. extern char *copyright;
  82.  
  83. int main(int argc,char *argv[])
  84. {
  85.     int i,j,fname=0;
  86.     c_flags_val[9].f=dontwarn;
  87.     c_flags_val[10].f=warn;
  88.     for(i=1;i<argc;i++){
  89.         if(*argv[i]!='-'){  /*  kein Flag   */
  90.             if(fname){
  91.                 error(1);
  92.             }else fname=i;
  93.         }else{
  94.             int flag=0;
  95.             for(j=0;j<MAXCF&&flag==0;j++){
  96.                 size_t l;
  97.                 if(!c_flags_name[j]) continue;
  98.                 l=strlen(c_flags_name[j]);
  99.                 if(l>0&&!strncmp(argv[i]+1,c_flags_name[j],l)){
  100.                     flag=1;
  101.                     if((c_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  102.                     c_flags[j]|=USEDFLAG;
  103.                     if(c_flags[j]&STRINGFLAG){
  104.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  105.                         if(argv[i][l+2]||i>=argc-1)
  106.                             c_flags_val[j].p=&argv[i][l+2];
  107.                         else
  108.                             c_flags_val[j].p=&argv[++i][0];
  109.                     }
  110.                     if(c_flags[j]&VALFLAG){
  111.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  112.                         if(argv[i][l+2]||i>=argc-1)
  113.                             c_flags_val[j].l=atol(&argv[i][l+2]);
  114.                         else
  115.                             c_flags_val[j].l=atol(&argv[++i][0]);
  116.                     }
  117.                     if(c_flags[j]&FUNCFLAG) c_flags_val[j].f(&argv[i][l+1]);
  118.                 }
  119.             }
  120.             for(j=0;j<MAXGF&&flag==0;j++){
  121.                 size_t l;
  122.                 if(!g_flags_name[j]) continue;
  123.                 l=strlen(g_flags_name[j]);
  124.                 if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){
  125.                     flag=1;
  126.                     if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  127.                     g_flags[j]|=USEDFLAG;
  128.                     if(g_flags[j]&STRINGFLAG){
  129.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  130.                         if(argv[i][l+2]||i>=argc-1)
  131.                             g_flags_val[j].p=&argv[i][l+2];
  132.                         else
  133.                             g_flags_val[j].p=&argv[++i][0];
  134.                     }
  135.                     if(g_flags[j]&VALFLAG){
  136.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  137.                         if(argv[i][l+2]||i>=argc-1)
  138.                             g_flags_val[j].l=atol(&argv[i][l+2]);
  139.                         else
  140.                             g_flags_val[j].l=atol(&argv[++i][0]);
  141.                     }
  142.                     if(g_flags[j]&FUNCFLAG) g_flags_val[j].f(&argv[i][l+1]);
  143.                 }
  144.             }
  145.             if(!flag){error(5,argv[i]);}
  146.         }
  147.     }
  148.     if(!(c_flags[6]&USEDFLAG)){
  149.       printf("%s\n",copyright);
  150.       printf("%s\n",cg_copyright);
  151.     }
  152.     if(!(c_flags[17]&USEDFLAG)) pp_init();
  153.     if(!(c_flags[8]&USEDFLAG)) c_flags_val[8].l=10; /* max. Fehlerzahl */
  154.     if(c_flags[22]&USEDFLAG) c_flags[7]|=USEDFLAG;   /*  iso=ansi */
  155.     if(c_flags[7]&USEDFLAG) error(209);
  156.     if(c_flags[0]&USEDFLAG) optflags=c_flags_val[0].l;
  157.     if(c_flags[11]&USEDFLAG) maxoptpasses=c_flags_val[11].l;
  158.     if(c_flags[12]&USEDFLAG) inline_size=c_flags_val[12].l;
  159.     if(c_flags[21]&USEDFLAG) fp_assoc=1;
  160.     if(c_flags[25]&USEDFLAG) unroll_size=c_flags_val[25].l;
  161.     if(c_flags[23]&USEDFLAG) noaliasopt=1;
  162.     if(!fname){error(6);}
  163.     inname=argv[fname];
  164.     strncpy(errfname,inname,FILENAME_MAX);    /*  das hier ist Muell - wird noch geaendert    */
  165.     if(!init_cg()) exit(EXIT_FAILURE);
  166.     if(c_flags[24]&USEDFLAG) multiple_ccs=0;
  167.     if(c_flags[17]&USEDFLAG){
  168.         in[0]=fopen(inname,"r");
  169.         if(!in[0]) {error(7,inname);}
  170.     }else{
  171.         if(!pp_include(inname)) error(7,inname);
  172.     }
  173.     if(!(c_flags[18]&USEDFLAG)&&!(c_flags[5]&USEDFLAG)){
  174.         if(c_flags[1]&USEDFLAG){
  175.             out=open_out(c_flags_val[1].p,0);
  176.         }else{
  177.             out=open_out(inname,"asm");
  178.         }
  179.         if(!out){
  180.             if(c_flags[17]&USEDFLAG){
  181.                 fclose(in[0]);
  182.             }else{
  183.                 pp_free();
  184.             }
  185.             exit(EXIT_FAILURE);
  186.         }
  187.     }
  188.     if(c_flags[2]&USEDFLAG) ic1=open_out(inname,"ic1");
  189.     if(c_flags[3]&USEDFLAG) ic2=open_out(inname,"ic2");
  190.     if(c_flags[18]&USEDFLAG) ppout=open_out(inname,"i");
  191.     if(c_flags[4]&USEDFLAG) DEBUG=c_flags_val[4].l; else DEBUG=0;
  192.     switch_count=0;break_label=0;
  193.     *string=0;s=string;line=0;
  194.     killsp();
  195.     nesting=-1;enter_block();
  196.     translation_unit();
  197. }
  198. int mcmp(const char *s1,const char *s2)
  199. /*  Einfachere strcmp-Variante.     */
  200. {
  201.     char c;
  202.     do{
  203.         c=*s1++;
  204.         if(c!=*s2++) return(1);
  205.     }while(c);
  206.     return(0);
  207. }
  208. void cpbez(char *m,int check_keyword)
  209. /*  Kopiert den naechsten Bezeichner von s nach m. Wenn check_keyord!=0 */
  210. /*  wird eine Fehlermeldung ausgegeben, falls das Ergebnis ein          */
  211. /*  reserviertes Keyword von C ist.                                     */
  212. {
  213.     char *p=m,*last=m+MAXI-1;int warned=0;
  214.     if(DEBUG&128) printf("Before cpbez:%s\n",s);
  215.     while(isalpha((unsigned char)*s)||isdigit((unsigned char)*s)||*s=='_'){
  216.         if(m<last){
  217.             *m++=*s++;
  218.         }else{
  219.             s++;
  220.             if(!warned){
  221.                 error(206,MAXI-1);
  222.                 warned=1;
  223.             }
  224.         }
  225.     }
  226.     *m=0;
  227.     if(DEBUG&128) printf("After cpbez:%s\n",s);
  228.     if(check_keyword){
  229.         char *n=p+1;
  230.         switch(*p){
  231.         case 'a': if(!mcmp(n,"uto")) error(216,p);
  232.                   return;
  233.         case 'b': if(!mcmp(n,"reak")) error(216,p);
  234.                   return;
  235.         case 'c': if(!mcmp(n,"ase")) error(216,p);
  236.                   if(!mcmp(n,"har")) error(216,p);
  237.                   if(!mcmp(n,"onst")) error(216,p);
  238.                   if(!mcmp(n,"ontinue")) error(216,p);
  239.                   return;
  240.         case 'd': if(!mcmp(n,"efault")) error(216,p);
  241.                   if(!mcmp(n,"o")) error(216,m);
  242.                   if(!mcmp(n,"ouble")) error(216,p);
  243.                   return;
  244.         case 'e': if(!mcmp(n,"lse")) error(216,p);
  245.                   if(!mcmp(n,"num")) error(216,p);
  246.                   if(!mcmp(n,"xtern")) error(216,p);
  247.                   return;
  248.         case 'f': if(!mcmp(n,"loat")) error(216,p);
  249.                   if(!mcmp(n,"or")) error(216,p);
  250.                   return;
  251.         case 'g': if(!mcmp(n,"oto")) error(216,p);
  252.                   return;
  253.         case 'i': if(!mcmp(n,"f")) error(216,p);
  254.                   if(!mcmp(n,"nt")) error(216,p);
  255.                   return;
  256.         case 'l': if(!mcmp(n,"ong")) error(216,p);
  257.                   return;
  258.         case 'r': if(!mcmp(n,"egister")) error(216,p);
  259.                   if(!mcmp(n,"eturn")) error(216,p);
  260.                   return;
  261.         case 's': if(!mcmp(n,"hort")) error(216,p);
  262.                   if(!mcmp(n,"igned")) error(216,p);
  263.                   if(!mcmp(n,"izeof")) error(216,p);
  264.                   if(!mcmp(n,"tatic")) error(216,p);
  265.                   if(!mcmp(n,"truct")) error(216,p);
  266.                   if(!mcmp(n,"witch")) error(216,p);
  267.                   return;
  268.         case 't': if(!mcmp(n,"ypedef")) error(216,p);
  269.                   return;
  270.         case 'u': if(!mcmp(n,"nion")) error(216,p);
  271.                   if(!mcmp(n,"nsigned")) error(216,p);
  272.                   return;
  273.         case 'v': if(!mcmp(n,"oid")) error(216,p);
  274.                   if(!mcmp(n,"olatile")) error(216,p);
  275.                   return;
  276.         case 'w': if(!mcmp(n,"hile")) error(216,p);
  277.                   return;
  278.         default : return;
  279.         }
  280.     }
  281. }
  282. void cpnum(char *m)
  283. /* kopiert die naechste int-Zahl von s nach m   */
  284. /* muss noch erheblich erweiter werden          */
  285. {
  286.     if(DEBUG&128) printf("Before cpnum:%s\n",s);
  287.     while(isdigit((unsigned char)*s)) *m++=*s++;
  288.     *m++=0;
  289.     if(DEBUG&128) printf("After cpnum:%s\n",s);
  290.  
  291. }
  292. static void killsp2(void)
  293. {
  294.     while(isspace((unsigned char)*s)) s++;
  295. }
  296. void killsp(void)
  297. /*  Ueberspringt Fuellzeichen                   */
  298. /*  noch einige unschoene Dinge drin            */
  299. {
  300.     int r;
  301.     if(DEBUG&128) printf("Before killsp:%s\n",s);
  302.     if(eof) raus();
  303.     while(isspace((unsigned char)*s)){
  304. /*        if(*s=='\n') {line++;if(DEBUG&1) printf("Line %d\n",line);}*/
  305.         s++;
  306.     }
  307.     if(*s==0){
  308.         do{
  309.             if(c_flags[17]&USEDFLAG) r=(fgets(string,MAXINPUT,in[0])!=0);
  310.                 else                 r=pp_nextline();
  311.             if(!r){
  312.                 /*raus();*/
  313.                 if(DEBUG&1) printf("nextline/fgets returned 0\n");
  314.                 s=string;*s=0;
  315.                 eof=1;
  316.                 return;
  317.             }else{
  318.                 line++;
  319.                 read_new_line=1;
  320.                 if(DEBUG&1) printf("Line %d\n",line);
  321.                 if(!strncmp("#pragma",string,7)){
  322.                     error(163);
  323.                     s=string+7;
  324.                     killsp2();
  325.                     if(!strncmp("opt",s,3)){
  326.                         s+=3;killsp2();
  327.                         c_flags_val[0].l=atol(s);
  328.                         if(DEBUG&1) printf("#pragma opt %ld\n",c_flags_val[0].l);
  329.                     }
  330.                     else if(!strncmp("printflike",s,10)){
  331.                         struct Var *v;
  332.                         s+=10;killsp2();
  333.                         cpbez(buff,0);
  334.                         if(DEBUG&1) printf("printflike %s\n",buff);
  335.                         v=find_var(buff,0);
  336.                         if(v){
  337.                             v->flags|=PRINTFLIKE;
  338.                             if(DEBUG&1) printf("succeeded\n");
  339.                         }
  340.                     }
  341.                     else if(!strncmp("scanflike",s,9)){
  342.                         struct Var *v;
  343.                         s+=9;killsp2();
  344.                         cpbez(buff,0);
  345.                         if(DEBUG&1) printf("scanflike %s\n",buff);
  346.                         v=find_var(buff,0);
  347.                         if(v){
  348.                             v->flags|=SCANFLIKE;
  349.                             if(DEBUG&1) printf("succeeded\n");
  350.                         }
  351.                     }
  352.                     else if(!strncmp("only-inline",s,11)){
  353.                         s+=11;killsp2();
  354.                         if(!strncmp("on",s,2)){
  355.                             if(DEBUG&1) printf("only-inline on\n");
  356.                             only_inline=1;
  357.                         }else{
  358.                             if(DEBUG&1) printf("only-inline off\n");
  359.                             only_inline=2;
  360.                         }
  361.                     }
  362.                     else if(!strncmp("type",s,4)){
  363.                     /*  Typ eines Ausdrucks im Klartext ausgeben    */
  364.                         np tree;
  365.                         s+=4;strcat(s,";");
  366.                         tree=expression();
  367.                         if(tree&&type_expression(tree)){
  368.                             printf("type of %s is:\n",string+7);
  369.                             prd(stdout,tree->ntyp);printf("\n");
  370.                         }
  371.                         if(tree) free_expression(tree);
  372.                     }
  373.                     else if(!strncmp("tree",s,4)){
  374.                     /*  gibt eine expression aus    */
  375.                         np tree;
  376.                         s+=4;strcat(s,";");
  377.                         tree=expression();
  378.                         if(tree&&type_expression(tree)){
  379.                             printf("tree of %s is:\n",string+7);
  380.                             pre(stdout,tree);printf("\n");
  381.                         }
  382.                         if(tree) free_expression(tree);
  383.                     }
  384.                 }
  385.                 if(string[0]=='#'&&isspace((unsigned char)string[1])&&isdigit((unsigned char)string[2])){
  386.                     sscanf(string+2,"%d \" %[^\"]",&line,errfname);
  387.                     if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
  388.                     line--;
  389.                 }
  390.                 if(!strncmp("#line ",string,6)){
  391.                     sscanf(string+6,"%d \" %[^\"]",&line,errfname);
  392.                     if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
  393.                     line--;
  394.                 }
  395.                 s=string;
  396.             }
  397.         }while(*s=='#');
  398.         killsp();
  399.     }
  400.     if(DEBUG&128) printf("After killsp:%s\n",s);
  401. }
  402. void enter_block(void)
  403. /*  Setzt Zeiger/Struckturen bei Eintritt in neuen Block    */
  404. {
  405.     if(nesting>=MAXN){error(9,nesting);return;}
  406.     nesting++;
  407.     if(DEBUG&1) printf("enter block %d\n",nesting);
  408.     first_ilist[nesting]=last_ilist[nesting]=0;
  409.     first_sd[nesting]=last_sd[nesting]=0;
  410.     first_si[nesting]=last_si[nesting]=0;
  411.     first_var[nesting]=last_var[nesting]=0;
  412.     if(nesting==1){
  413.         first_llist=last_llist=0;
  414.         first_clist=last_clist=0;
  415.         merk_varf=merk_varl=0;
  416.         merk_ilistf=merk_ilistl=0;
  417.         merk_sif=merk_sil=0;
  418. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  419. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  420. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  421. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  422. /*        merk_sdf=merk_sdl=0;*/
  423.         afterlabel=0;
  424.     }
  425. }
  426. void leave_block(void)
  427. /*  Setzt Zeiger/Struckturen bei Verlassen eines Blocks     */
  428. {
  429.     int i;
  430.     for(i=1;i<=MAXR;i++)
  431.         if(regbnesting[i]==nesting) regsbuf[i]=0;
  432.  
  433.     if(nesting<0){error(10);return;}
  434.     if(DEBUG&1) printf("leave block %d\n",nesting);
  435.     if(nesting>0){
  436.         if(merk_varl) merk_varl->next=first_var[nesting]; else merk_varf=first_var[nesting];
  437.         if(last_var[nesting]) merk_varl=last_var[nesting];
  438.         if(merk_sil) merk_sil->next=first_si[nesting]; else merk_sif=first_si[nesting];
  439.         if(last_si[nesting]) merk_sil=last_si[nesting];
  440.         if(merk_sdl) merk_sdl->next=first_sd[nesting]; else merk_sdf=first_sd[nesting];
  441.         if(last_sd[nesting]) merk_sdl=last_sd[nesting];
  442.         if(merk_ilistl) merk_ilistl->next=first_ilist[nesting]; else merk_ilistf=first_ilist[nesting];
  443.         if(last_ilist[nesting]) merk_ilistl=last_ilist[nesting];
  444.     }
  445.     if(nesting==1){
  446.         if(merk_varf) gen_vars(merk_varf);
  447.         if(first_llist) free_llist(first_llist);
  448.         if(first_clist) free_clist(first_clist);
  449.         if(merk_varf) free_var(merk_varf);
  450.         if(merk_sif) free_si(merk_sif);
  451. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  452. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  453. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  454. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  455. /*        if(merk_sdf) free_sd(merk_sdf);*/
  456.         if(merk_ilistf) free_ilist(merk_ilistf);
  457.     }
  458.     if(nesting==0){
  459. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  460. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  461. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  462. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  463.         if(merk_sdf) free_sd(merk_sdf);
  464.         if(first_var[0]) gen_vars(first_var[0]);
  465.         if(first_var[0]) free_var(first_var[0]);
  466.         if(first_sd[0]) free_sd(first_sd[0]);
  467.         if(first_si[0]) free_si(first_si[0]);
  468.         if(first_ilist[0]) free_ilist(first_ilist[0]);
  469.     }
  470.     nesting--;
  471. }
  472. void pra(FILE *f,struct argument_list *p)
  473. /*  Gibt argument_list umgekehrt auf Bildschirm aus             */
  474. {
  475.     if(p->next){ pra(f,p->next);fprintf(f,",");}
  476.     if(p->arg) pre(f,p->arg);
  477. }
  478. void pre(FILE *f,np p)
  479. /*  Gibt expression auf Bildschirm aus                          */
  480. {
  481.     int c;
  482.     c=p->flags;
  483.     if(p->sidefx) fprintf(f,"/");
  484.     if(p->lvalue) fprintf(f,"|");
  485.     if(c==CALL){fprintf(f,"call-function(");pre(f,p->left);fprintf(f,")(");
  486.                 if(p->alist) pra(f,p->alist);
  487.                 fprintf(f,")");return;}
  488.     if(c==CAST){fprintf(f,"cast(");pre(f,p->left);
  489.                 fprintf(f,"->");prd(f,p->ntyp);
  490.                 fprintf(f,")");return;}
  491.     if(c==MEMBER){if(p->identifier) fprintf(f,".%s",p->identifier);return;}
  492.     if(c==IDENTIFIER){if(p->identifier) fprintf(f,"%s",p->identifier);
  493.         fprintf(f,"+");printval(f,&p->val,LONG,1); return;}
  494.     fprintf(f,"%s(",ename[c]);
  495.     if(p->left) pre(f,p->left);
  496.     if(p->right){
  497.         fprintf(f,",");
  498.         pre(f,p->right);
  499.     }
  500.     fprintf(f,")");
  501.     if(c==CEXPR||c==PCEXPR){fprintf(f,"(value="); printval(f,&p->val,p->ntyp->flags,1); fprintf(f,")");}
  502. }
  503.  
  504. void error(int errn,...)
  505. /*  Behandelt Ausgaben wie Fehler und Meldungen */
  506. {
  507.     int type;
  508.     va_list vl;char *errstr="",*txt;
  509.     if(errn==-1) errn=158;
  510.     type=err_out[errn].flags;
  511.     if(type&DONTWARN) return;
  512.     va_start(vl,errn);
  513.     if(type&WARNING) errstr="warning";
  514.     if(type&ERROR) errstr="error";
  515.     if(type&NOLINE){
  516.         printf("%s %d: ",errstr,errn);
  517.     }else if(type&INFUNC){
  518.         if((type&INIC)&&err_ic&&err_ic->line){
  519.             if(!(c_flags[17]&USEDFLAG)) txt=filename[incnesting];
  520.                 else txt=errfname;
  521.             printf("%s %d in line %d of \"%s\": ",errstr,errn,err_ic->line,txt);
  522.         }else{
  523.             printf("%s %d in function \"%s\": ",errstr,errn,cur_func);
  524.         }
  525.     }else{
  526.         int n;
  527.         {if(eof) printf(">EOF\n"); else printf(">%s",string);}
  528.         if(!(c_flags[17]&USEDFLAG)){
  529.             printf("\n");
  530.             n=linenr;txt=filename[incnesting];
  531.         }else{
  532.             n=line;txt=errfname;
  533.         }
  534.         if(c_flags[20]&USEDFLAG){   /*  strip-path from filename */
  535.             char *p=txt,c;
  536.             while(c=*p++)
  537.                 if(c==':'||c=='/'||c=='\\') txt=p;
  538.         }
  539.         printf("%s %d in line %d of \"%s\": ",errstr,errn,n,txt);
  540.     }
  541.     vprintf(err_out[errn].text,vl);
  542.     printf("\n");
  543.     va_end(vl);
  544.     if(type&ERROR){
  545.         errors++;
  546.         if(c_flags_val[8].l&&c_flags_val[8].l<=errors)
  547.             {printf("Maximum number of errors reached!\n");raus();}
  548.     }
  549.     if(type&FATAL){printf("aborting...\n");raus();}
  550. }
  551. FILE *open_out(char *name,char *ext)
  552. /*  Haengt ext an name an und versucht diese File als output zu oeffnen */
  553. {
  554.     char *s,*p;FILE *f;
  555.     if(ext){
  556.         s=mymalloc(strlen(name)+strlen(ext)+2);
  557.         strcpy(s,name);
  558.         p=s+strlen(s);
  559.         while(p>=s){
  560.             if(*p=='.'){*p=0;break;}
  561.             p--;
  562.         }
  563.         strcat(s,".");
  564.         strcat(s,ext);
  565.     }else s=name;
  566.     f=fopen(s,"w");
  567.     if(!f) printf("Couldn't open <%s> for output!\n",s);
  568.     if(ext) free(s);
  569.     return(f);
  570. }
  571.